package com.un.ebs.order.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.un.ebs.core.common.GroupListInfo;
import com.un.ebs.core.util.SecurityUtils;
import com.un.ebs.core.util.WebResult;
import com.un.ebs.core.util.WebUtils;
import com.un.ebs.memorial.dto.OrderWxPayResponse;
import com.un.ebs.order.domain.OrderExt;
import com.un.ebs.order.domain.OrderItemExt;
import com.un.ebs.order.domain.OrderPaymentExt;
import com.un.ebs.order.domain.OrderReportExt;
import com.un.ebs.order.dto.*;
import com.un.ebs.order.enums.OrderStatusEnum;
import com.un.ebs.order.mapper.OrderPaymentExtMapper;
import com.un.ebs.order.service.OrderService;
import com.un.ebs.product.dto.ProductClassOrderAttrVO;
import com.un.ebs.sys.dto.PersonnelDto;
import com.un.ebs.sys.service.UserService;
import com.un.ebs.sys.service.WxService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;


/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author liubo
 * @since 2019-11-16
 */
@RestController()
@RequestMapping("/order")
@Api(value = "order", description = "订单")
public class OrderController {

    @Autowired
    private OrderService service;

    @Autowired
    private UserService userService;

    @Autowired
    private WxService wxService;

    @Autowired
    private OrderPaymentExtMapper orderPaymentExtMapper;

    @PostMapping("add")
    @ApiOperation("添加")
    public WebResult save(@RequestBody OrderAddDto req) {
        return WebUtils.success(service.add(req));
    }

    @PostMapping("addAndSubmit")
    @ApiOperation("添加并提交")
    public WebResult addAndSubmit(@RequestBody OrderAddDto req) {
        String id = service.add(req);
        service.submit(id);
        return WebUtils.success(id);
    }

    @RequestMapping("wxPayNotify/{openId}/{orderId}")
    @ApiOperation("微信支付回调")
    public String wxPayNotify(@PathVariable String openId, @PathVariable String orderId, @RequestBody String xmlData) throws Exception {
        OrderVo order = service.queryById(orderId);
        WxPayOrderNotifyResult notifyResult = wxService.getWxPayService(order.getTenantId()).parseOrderNotifyResult(xmlData);

        OrderPayDto pay = new OrderPayDto();
        pay.setOrderId(orderId);
        pay.setMoney(notifyResult.getCashFee() / 100.00d);
        pay.setPayDict("wxpay");
        service.payment(pay, userService.getUserByOpenId(openId).getId());

        return WxPayNotifyResponse.success("成功");
    }

    @PostMapping("buy")
    @ApiOperation("直接下单并提交")
    public WebResult<WxPayUnifiedOrderResult> buy(@RequestBody OrderSimpleAddDto req) throws NoSuchAlgorithmException, WxPayException, UnsupportedEncodingException {
        String id = service.addSimple(req);
        return WebUtils.success(service.preWxPay(id, null));
    }

    @PostMapping(value = "addFile")
    @ApiOperation("向订单明细添加附件，请求中需要包括：itemId,attrId，file两个参数")
    public WebResult<List<String>> addFile(MultipartHttpServletRequest request) {
        MultipartHttpServletRequest multipartRequest = request;
        String itemId = multipartRequest.getParameter("itemId");
        String attrId = multipartRequest.getParameter("attrId");
        //提交的文件列表
        List<MultipartFile> files = multipartRequest.getFiles("file");

        return WebUtils.success(service.addFile(itemId, attrId, files));
    }

    @PostMapping("submitFile")
    @ApiOperation("提交文件")
    public WebResult submitFile(@RequestParam String itemId) {
        service.submitFile(itemId);
        return WebUtils.success();
    }

    @PostMapping("cancelSubmitFile")
    @ApiOperation("撤销文件提交，需要重新上传")
    public WebResult cancelSubmitFile(@RequestParam String itemId, @RequestParam String desc) {
        service.cancelSubmitFile(itemId, desc);
        return WebUtils.success();
    }

    @PostMapping("removeFile")
    @ApiOperation("删除订单明细中的附件")
    public WebResult removeFile(@RequestParam String fileId) {
        service.removeFile(fileId);
        return WebUtils.success();
    }

    @PostMapping("update")
    @ApiOperation("修改")
    public WebResult update(@RequestBody OrderUpdateDto req) {
        service.update(req);
        return WebUtils.success();
    }

    @PostMapping("updatePlanDeliver")
    @ApiOperation("修改订单项的计划交付时间和备注")
    public WebResult updatePlanDeliver(@RequestParam String orderId, @RequestBody List<OrderItemUpdateDto> req) {
        service.updatePlanDeliver(orderId, req);
        return WebUtils.success();
    }

    @PostMapping("updateQtyAndPrice")
    @ApiOperation("修改订单项的计划交付时间和备注的同时，修改数量和价格")
    public WebResult updateQtyAndPrice(@RequestBody OrderItemUpdateQtyAndPriceDto req) {
        service.updateQtyAndPrice(req);
        return WebUtils.success();
    }

    @PostMapping("delete")
    @ApiOperation("删除")
    public WebResult delete(@RequestParam String id) {
        service.delete(id);
        return WebUtils.success();
    }

    @PostMapping("submit")
    @ApiOperation("提交")
    public WebResult submit(@RequestParam String id) throws NoSuchAlgorithmException, WxPayException, UnsupportedEncodingException {
        service.submit(id);
        return WebUtils.success();
    }

    @PostMapping("submitCancel")
    @ApiOperation("提交撤销")
    public WebResult submitCancel(@RequestParam String id, @RequestParam(required = false) String remark, @RequestParam(required = false) @ApiParam("退款的付款方式") String payDict, @RequestParam(required = false) @ApiParam("退款金额") Double money) {
        service.submitCancel(id, remark, payDict, money);
        return WebUtils.success();
    }

    @PostMapping("expireApply")
    @ApiOperation(value = "支付延期申请")
    public WebResult expireApply(@RequestBody OrderExpireApplyDto req) {
        service.expireApply(req);
        return WebUtils.success();
    }

    @PostMapping("expireApplyAudit")
    @ApiOperation(value = "支付延期审批")
    public WebResult expireApplyAudit(@RequestBody OrderExpireApplyAuditDto req) {
        service.expireApplyAudit(req);
        return WebUtils.success();
    }

    @PostMapping("discountApply")
    @ApiOperation(value = "优惠申请")
    public WebResult discountApply(@RequestBody @Validated OrderDiscountApplyDto req) {
        service.discountApply(req);
        return WebUtils.success();
    }

    @PostMapping("discountApplyAudit")
    @ApiOperation(value = "优惠审批")
    public WebResult discountApplyAudit(@RequestBody @Validated OrderDiscountApplyAuditDto req) {
        service.discountApplyAudit(req);
        return WebUtils.success();
    }

    @PostMapping("accept")
    @ApiOperation("受理")
    public WebResult accept(@RequestParam String id) {
        service.accept(id);
        return WebUtils.success();
    }

    @PostMapping("deliver")
    @ApiOperation("结算")
    public WebResult deliver(@RequestParam String id) {
        service.deliver(id);
        return WebUtils.success();
    }

    @PostMapping("deliverItem")
    @ApiOperation("交付")
    public WebResult deliverItem(@RequestParam String id) {
        service.deliverItem(id);
        return WebUtils.success();
    }

    @PostMapping("payment")
    @ApiOperation("支付")
    public WebResult payment(@RequestBody OrderPayDto req) {
        service.payment(req, SecurityUtils.getUserContent().getId());
        return WebUtils.success();
    }

    @PostMapping("/payment/wx")
    @ApiOperation("微信支付支付")
    public WebResult<OrderWxPayResponse> payment(@RequestParam String id, @RequestParam(required = false) String openId) throws NoSuchAlgorithmException, WxPayException, UnsupportedEncodingException {
        return WebUtils.success(service.preWxPay(id, openId));
    }

    @PostMapping("paymentBack")
    @ApiOperation("退款")
    public WebResult paymentBack(@RequestBody OrderPayDto req) {
        service.paymentBack(req);
        return WebUtils.success();
    }

    @GetMapping("listPayment")
    @ApiOperation("收款记录")
    public WebResult<OrderPaymentExt> listPayment(@RequestParam String id) {
        LambdaQueryWrapper<OrderPaymentExt> lq = Wrappers.lambdaQuery();
        lq.eq(OrderPaymentExt::getOrderId, id);
        lq.orderByAsc(OrderPaymentExt::getCreateTime);
        return WebUtils.success(orderPaymentExtMapper.selectList(lq));
    }

    @GetMapping("{id}")
    @ApiOperation("根据主键获取单个 Order")
    public WebResult<OrderVo> getId(@PathVariable("id") String id) {
        return WebUtils.success(service.queryById(id));
    }

    @GetMapping("/detail/{id}")
    @ApiOperation("根据主键获取单个 Order")
    public WebResult<OrderVo> getIdByNotAuth(@PathVariable("id") String id) {
        return WebUtils.success(service.queryById(id));
    }

    @GetMapping("bzorder/{id}")
    @ApiOperation("根据主键获取单个 Order")
    public WebResult<OrderBzVo> getBzOrderByCustId(@PathVariable("id") String id) {
        return WebUtils.success(service.queryBzOrderByCustId(id));
    }

    @GetMapping("list")
    @ApiOperation("查询订单")
    public WebResult<IPage<OrderExt>> list(@RequestParam(required = false) @ApiParam("支持订单号、客户姓名、客户电话字段") String searchText, @RequestParam OrderStatusEnum status, @RequestParam int pageIndex, @RequestParam int pageSize) {
        return WebUtils.success(service.query(null, searchText, status, pageSize, pageIndex));
    }

    @GetMapping("listStatusCount")
    @ApiOperation("当前用户的订单分类查询与订单明细")
    public WebResult<List<GroupListInfo<OrderVo>>> listStatusCount() {
        return WebUtils.success(service.queryStatusCountByUserId(SecurityUtils.getUserContent().getId()));
    }

    @GetMapping("list/items")
    @ApiOperation("查询订单明细")
    public WebResult<IPage<OrderItemExt>> listItem(
            @RequestParam(required = false) @ApiParam("支持订单号、客户姓名、客户电话、商品名称、订单提交人、订单受理人、交付人字段") String searchText,
            @RequestParam OrderStatusEnum status,
            @RequestParam Integer pageIndex,
            @RequestParam Integer pageSize) {
        return WebUtils.success(service.queryItem(searchText, status, pageSize, pageIndex));
    }

    @GetMapping("myList")
    @ApiOperation("查询当前用户创建的订单")
    public WebResult<IPage<OrderExt>> myList(@RequestParam String searchText, @RequestParam OrderStatusEnum status, @RequestParam int pageIndex, @RequestParam int pageSize) {
        return WebUtils.success(service.query(SecurityUtils.getUserContent().getId(), searchText, status, pageSize, pageIndex));
    }

    @GetMapping("payment/timeout")
    @ApiOperation("付款超过订单")
    public WebResult<IPage<OrderExt>> queryPaymentTimeout(@RequestParam int pageIndex, @RequestParam int pageSize) {
        return WebUtils.success(service.queryPaymentTimeOut(pageSize, pageIndex));
    }

    @GetMapping("myPlanDeliverItem")
    @ApiOperation("查询当前的计划交付的订单项")
    public WebResult<List<OrderItemPlanDeliverDto>> myPlanDeliverItem() {
        return WebUtils.success(service.queryPlanDeliverItem(null));
    }

    @GetMapping("listPlanDeliverItemByTimePeriod")
    @ApiOperation("查询交付计划，按时间周期")
    public WebResult<List<OrderItemPlanDeliverDto>> listPlanDeliverItemBy(@RequestParam(required = false) String searchText) {
        return WebUtils.success(service.queryPlanDeliverItemByTimePeriod(searchText));
    }

    @GetMapping("listPlanDeliverItem")
    @ApiOperation("查询交付计划，按已生成的工单数量")
    public WebResult<List<OrderItemPlanDeliverDto>> listPlanDeliverItem(@RequestParam(required = false) String searchText) {
        return WebUtils.success(service.queryPlanDeliverItem(searchText));
    }

    @GetMapping("queryOrerAttrBySkuId")
    @ApiOperation("查询订单属性，根据SKUID")
    public WebResult<List<ProductClassOrderAttrVO>> queryOrerAttrBySkuId(@RequestParam String id) {
        return WebUtils.success(service.convertOrderAttrToGroupList(service.queryOrderAttrBySkuId(id)));
    }

    @GetMapping("queryOrerAttrBySpuId")
    @ApiOperation("查询订单属性，SPUID")
    public WebResult<List<ProductClassOrderAttrVO>> queryOrerAttrBySpuId(@RequestParam String id) {
        return WebUtils.success(service.convertOrderAttrToGroupList(service.queryOrderAttrBySpuId(id)));
    }

    @GetMapping("queryOrderAttrByOrderId")
    @ApiOperation("查询订单属性，SPUID")
    public WebResult<List<ProductClassOrderAttrVO>> queryOrerAttrByOrderId(@RequestParam String id) {
        return WebUtils.success(service.convertOrderAttrVoToGroupList(service.queryOrderAttrByOrderId(id)));
    }

    @GetMapping("listBook")
    @ApiOperation("查询可预约记录")
    public WebResult<List<OrderItemBookByDto>> queryBook(@RequestParam(required = false) @ApiParam("如果为空，则默认当前用户") String custId) {
        return WebUtils.success(service.queryBookRec(custId));
    }

    @GetMapping("listExpireAuditPersonnel")
    @ApiOperation("查询订单延期支付审批人列表")
    public WebResult<List<PersonnelDto>> queryExpireAuditPersonnel(@RequestParam String orderId) {
        return WebUtils.success(service.queryExpireAuditPersonnel());
    }

    @GetMapping("listDiscountAuditPersonnel")
    @ApiOperation("查询订单优惠审核人列表")
    public WebResult<List<PersonnelDto>> queryDiscountAuditPersonnel(@RequestParam String orderId, @RequestParam Double discountMoney) {
        return WebUtils.success(service.queryDiscountAuditPersonnel(orderId, discountMoney));
    }

    @GetMapping("listItemByDefunct")
    @ApiOperation("查询订单延期支付审批人列表")
    public WebResult<List<OrderItemByDefunct>> queryItemByDefunct(@RequestParam String defunctIds) {
        return WebUtils.success(service.queryItemByDefunct(defunctIds));
    }

    @GetMapping("listSaleReport")
    @ApiOperation("销售报表")
    public WebResult<IPage<OrderReportExt>> querySaleReport(@RequestParam String searchText, @RequestParam Date start, @RequestParam Date end, @RequestParam Integer pageSize, @RequestParam Integer pageIndex) {
        return WebUtils.success(service.querySaleReport(searchText, start, end, pageSize, pageIndex));
    }
}